package com.zhijian.warehouse.manage.service.impl;

import com.gg.reader.api.dal.GClient;
import com.zhijian.util.AssertUtil;
import com.zhijian.util.BeanUtil;
import com.zhijian.util.MapBuilderUtil;
import com.zhijian.warehouse.manage.config.access.AccessConfig;
import com.zhijian.warehouse.manage.entity.po.AccessDoorDeploy;
import com.zhijian.warehouse.manage.entity.vo.request.AccessDoorDeploySearchVo;
import com.zhijian.warehouse.manage.entity.vo.request.AccessFacilityRecordSaveOrUpdateVo;
import com.zhijian.warehouse.manage.entity.vo.response.AccessDoorDeployVo;
import com.zhijian.warehouse.manage.enums.SseClientEnum;
import com.zhijian.warehouse.manage.service.*;
import com.zhijian.warehouse.manage.service.sse.SseMessage;
import com.zhijian.warehouse.manage.util.access.AccessUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import static java.lang.Thread.sleep;

/**
 * 通道门设置业务处理层
 *
 * @author auto
 * @version: 1.0
 * @date 2024-11-03 15:31:18
 */
@Slf4j
@Service
public class AccessOptServiceImpl implements AccessOptService {
    private final String CACHE_KEY_RFID = "access_facility_record:%s";
    @Autowired
    private AccessDoorDeployService accessDoorDeployService;
    @Autowired
    private AccessFacilityRecordService accessFacilityRecordService;
    @Autowired
    private AccessConfig accessConfig;
    @Autowired
    private AccessOptService accessOptService;
    @Autowired
    private AccessNotifyService accessNotifyService;
    @Autowired
    private CacheDao cacheDao;


    @Override
    public List<AccessDoorDeployVo> selectDoorList(AccessDoorDeploySearchVo build) {
        return accessDoorDeployService.selectList(build);
    }

    @Override
    public void saveDoorRecord(AccessFacilityRecordSaveOrUpdateVo accessDoorDeployVo, String epc) {
        //保存过门记录
        //String epcRedis = cacheDao.support().get(String.format(CACHE_KEY_RFID, epc));
       // if (BeanUtil.isEmpty(epcRedis)) {
          // cacheDao.support().set(String.format(CACHE_KEY_RFID, epc), epc, 1, TimeUnit.SECONDS);//1分钟内重复过门不做处理
            try {
                accessFacilityRecordService.save(accessDoorDeployVo);
            } catch (Exception e) {
                log.error("保存过门记录失败", e);
            }
       // }
    }

    @Override
    public synchronized SseEmitter doorConnect(AccessDoorDeployVo accessDoorDeploy) {
        AccessDoorDeployVo accessDoorDeployVo = accessDoorDeployService.selectVoById(accessDoorDeploy.getId());
        SseEmitter sseEmitter = new SseEmitter(1000L);
        String msg = "";
        if (BeanUtil.isEmpty(accessDoorDeployVo))
            msg = "通道门记录不存在";
        else if (Objects.equals(accessDoorDeployVo.getStatus(), 1))
            msg = "通道门已连接";
        try {
            if (BeanUtil.isNotEmpty(msg)) {
                sseEmitter.send(SseMessage.builder().type(SseClientEnum.RECONNECT.type).data(MapBuilderUtil.builder()
                        .put("status", true)
                        .put("msg", msg)
                        .build()).build(), MediaType.APPLICATION_JSON);
                return sseEmitter;
            }
            AccessUtil.initAccess(new GClient(), accessConfig, accessOptService, accessDoorDeployVo);
            sleep(3000);//等待三秒发送消息
            return accessNotifyService.sendConnect(accessDoorDeploy.getId());
        } catch (IOException e) {
            log.error("连接通道门失败", e);
            AssertUtil.check(Objects.equals(accessDoorDeployVo.getStatus(), 0), "通道门连接失败");
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return null;
    }

    @Override
    public void closeDoorConnect(AccessDoorDeployVo accessDoorDeploy) {
        //TODO 逻辑待补充
    }

    @Override
    public void updateDoorDeployStatus(AccessDoorDeploy accessDoorDeploy) {
        accessDoorDeployService.updateByPrimaryKeySelective(AccessDoorDeploy.builder()
                .status(accessDoorDeploy.getStatus())
                .id(accessDoorDeploy.getId())
                .build());
    }

    @Override
    public void aioConnect(String epc, String androidIp) {
        accessNotifyService.rfIdConnect(epc, androidIp);
    }

    @Override
    public SseEmitter doorConnect(boolean flag, String msg, Long doorId) {
        return accessNotifyService.doorReconnect(flag, msg, doorId);
    }
}
